#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "TcpAcceptor.h"
#include "SocketSelector.h"


#pragma comment(lib, "ws2_32.lib")

#ifndef MAKEWORD
#define MAKEWORD(x, y) (x+y)
#endif

using namespace std;
using namespace vs::net;


void test_acceptor(int argc, char **argv)
{
	TcpAcceptor acceptor;
	InternetAddress listenAddr(atoi(argv[1]));
	acceptor.Listen(listenAddr);

	InternetAddress addr;
	TcpStream stream;
	// AsynTcpStream asyn_tcp_stream;
	if (!acceptor.Accept(addr, stream))
	{
		printf("accept failed\n");
		return;
	}
	else
	{
		printf("accept success\n");
	}

	char msg[1024] = "";
	char msg_to_client[32] = "MessageToClient";
	while (stream.Recv(msg, 1024) > 0)
	{
		printf("have received message (%s)\n", msg);
		memset(msg, 0, 1024);
		if (stream.Send(msg_to_client, strlen(msg_to_client)) > 0)
		{
			printf("have sent message (%s)\n", msg_to_client);
		}
		else
		{
			printf("sent message to client failed\n");
			break;
		}
	}
}


void test_asyn_acceptor(int argc, char **argv)
{
	AsynTcpAcceptor acceptor;
	InternetAddress listenAddr(atoi(argv[1]));
	acceptor.Listen(listenAddr);

	SocketSelector selector;
	selector.AddReadHandle(acceptor);
	struct timeval timeout = {1, 0};
	if (selector.Select(NULL) <= 0)
	{
		printf("select error\n");
		return;
	}

	if (selector.IsReadable(acceptor))
	{
		InternetAddress addr;
		TcpStream stream;
		// AsynTcpStream asyn_tcp_stream;
		if (!acceptor.Accept(addr, stream))
		{
			printf("accept failed\n");
			return;
		}
		else
		{
			printf("accept success\n");
		}

		char msg[1024] = "";
		char msg_to_client[32] = "MessageToClient";
		while (stream.Recv(msg, 1024) > 0)
		{
			printf("have received message (%s)\n", msg);
			memset(msg, 0, 1024);
			if (stream.Send(msg_to_client, strlen(msg_to_client)) > 0)
			{
				printf("have sent message (%s)\n", msg_to_client);
			}
			else
			{
				printf("sent message to client failed\n");
				break;
			}
		}
	}
}


int main(int argc, char **argv)
{
	if (argc < 2)
	{
		printf("%s listen_port\n", argv[0]);
		return 0;
	}

	NetInitializer init(MAKEWORD(2, 2));
	if (!init.IsNetworkReady())
	{
		printf("init network error\n");
		return -1;
	}
	
	test_acceptor(argc, argv);
	//test_asyn_acceptor(argc, argv);
	
	return 0;
}
